package com.hsm.framework;

import com.hsm.framework.annotation.Controller;
import com.hsm.framework.annotation.RequestMapping;
import com.hsm.framework.entity.MethodBean;
import com.hsm.framework.utils.ClassScannerUtils;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DispatcherServlet extends HttpServlet {

    private Map<String,MethodBean> map = new HashMap<String, MethodBean>();

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        try {
            //1.使用config对象获取Servlet初始化参数 获取包名
            String packageName = config.getInitParameter("packageName");

            //2.扫描某个包下的所有类，得到字节码对象集合list
            List<Class<?>> classes = ClassScannerUtils.getClasssFromPackage(packageName);

            //3.遍历字节码对象集合list
            for (Class<?> c : classes) {

                //4.判断该类上是否有@Controller注解，有就去遍历这个类中的所有Method  有返回true 没有返回false
                boolean flag = c.isAnnotationPresent(Controller.class);
                if (flag){
                    //5.获取Method方法上的@RequestMapping注解
                    Method[] methods = c.getMethods();
                    for (Method method : methods) {
                        RequestMapping annotation = method.getAnnotation(RequestMapping.class);

                        //7.如果获取到@RequestMapping注解对象不为空，获取注解的值value
                        if (annotation != null){
                            String value = annotation.value();
                            //8.将请求路径注解的value值和MethodBean存入map集合中  方便来了请求之后直接调用方法处理请求
                            MethodBean methodBean = new MethodBean(method, c.newInstance());
                            map.put(value,methodBean);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {

            //1.获取请求URI和项目部署路径 截取出请求映射路径
            String requestURI = request.getRequestURI();
            System.out.println("requestURI = " + requestURI);
            String contextPath = request.getContextPath();
            System.out.println("contextPath = " + contextPath);
            String path = requestURI.substring(contextPath.length(), requestURI.lastIndexOf("."));
            System.out.println("path = " + path);

            //2.根据请求映射路径  去map集合中找方法调用处理请求
            MethodBean methodBean = map.get(path);

            if(methodBean != null){
                methodBean.getMethod().invoke(methodBean.getObj(),request,response);
            }else {
                System.err.println("没有对应的方法处理...");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
